package priv.pfz.basedao.lab.performance;

import javassist.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @author yyjxp
 * 2024/8/4 15:36
 */
public class ReflectBytecodeUtilMethod implements ReflectTest {
    private Method utilMethod;

    public ReflectBytecodeUtilMethod() {
        try {
            ClassPool cp = ClassPool.getDefault();
            CtClass ctClass = cp.makeClass(TestBean.class.getName() + "$Test");

            CtClass returnType = CtClass.voidType;
            CtClass[] paramTypes = new CtClass[]{cp.get(TestBean.class.getName())};
            CtMethod ctMethod = new CtMethod(returnType, "callGetters", paramTypes, ctClass);
            ctMethod.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
            ctMethod.setBody("{" +
                    "$1.getA();\n" +
                    "$1.getB();\n" +
                    "$1.getC();\n" +
                    "$1.getD();\n" +
                    "$1.getE();\n" +
                    "$1.getA2();\n" +
                    "$1.getB2();\n" +
                    "$1.getC2();\n" +
                    "$1.getD2();\n" +
                    "$1.getE2();\n" +
                    "}");
            ctClass.addMethod(ctMethod);
            utilMethod = ctClass.toClass().getMethod("callGetters", TestBean.class);
            ctClass.detach();
        } catch (CannotCompileException | IllegalArgumentException | NotFoundException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String name() {
        return "反射调用字节码生成的方法";
    }

    @Override
    public void run(TestBean bean) {
        try {
            utilMethod.invoke(null, bean);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
}
